home *** CD-ROM | disk | FTP | other *** search
- {$X+,B-,V-} {essential compiler directives}
-
- Unit nwSema;
-
- { nwSema unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
-
- INTERFACE
-
- { Primary functions: Interrupt: comments:
-
- * CloseSemaphore (F220/04)
- * ExamineSemaphore (F220/01)
- * GetConnectionsSemaphores (F217/F1)
- * GetSemaphoreInformation (F217/F2)
- * OpenSemaphore (F220/00)
- * SignalSemaphore (F220/03)
- * WaitOnSemaphore (F220/02)
-
- Notes: Functions marked with a '*' have been tested and found correct.
- }
-
- Uses nwIntr,nwMisc;
-
- Type TsemaInfo=record
- ConnNbr:word;
- TaskNbr:word;
- end;
- TsemaInfoList=array[1..100] of TsemaInfo;
- { used by GetSemaphoreInformation }
-
- TconnSema=record
- OpenCount: Byte;
- Value : Integer;
- TaskNbr : Word;
- unknown : byte; { always 00 ?! }
- Name : string[127];
- end;
- { used by GetConnectionsSemaphores }
-
- Var Result:word;
-
- {F220/00 [2.15? 3.x]}
- Function OpenSemaphore(SemName : String; InitVal : Integer;
- VAR SemHandle : LongInt;
- VAR OpenCount : Word ):Boolean;
-
- {F220/01 [2.15? 3.x]}
- FUNCTION ExamineSemaphore( SemHandle :LongInt;
- VAR Value :Integer;
- VAR OpenCount :Word ) :Boolean;
- { This functions returns the current value and open count of a semaphore.}
-
- {F220/02 [3.x]}
- FUNCTION WaitOnSemaphore( SemHandle :LongInt;
- Wait_Time :Word ) :Boolean;
- { Decrement the semaphore value and, if it is negative, }
- { wait until it becomes non-negative or until a timeout occurs. }
-
- {F220/03 [3.x]}
- FUNCTION SignalSemaphore(SemHandle:LongInt) : Boolean;
- { Increment the semaphore value and release if waiting. }
-
- {F220/04 [3.x]}
- FUNCTION CloseSemaphore(SemHandle:LongInt) : Boolean;
- { Decrement the open count of a semaphore.}
- { When the open count goes to zero, the semaphore is destroyed. }
-
-
- {F217/F1 [2.15+? 3.x+]}
- Function GetConnectionsSemaphores(ConnNbr:Word;
- {i/o} Var seqNbr:Word;
- {out} Var NbrOfSemaLeft:Byte;
- {out} Var SemaInfo:TconnSema):Boolean;
- {Caller needs console privileges }
-
- {F217/F2 [2.15? 3.x+]}
- Function GetSemaphoreInformation(SemaName:String;
- {i/o} Var seqNbr:word;
- {out} Var OpenCount:word;
- Var SemValue:Integer;
- Var NbrOfSemaLeft:byte;
- Var info:TsemaInfoList):Boolean;
- { Caller needs console privileges }
-
-
- IMPLEMENTATION {=============================================================}
-
-
- {F220/00 [3.x]}
- Function OpenSemaphore(SemName : String; InitVal : Integer;
- VAR SemHandle : LongInt;
- VAR OpenCount : Word ):Boolean;
- Type Treq=Record
- subf:byte;
- _InitVal:byte;
- _SemNameLen:byte;
- _SemName:array[0..127] of byte;
- end;
- Trep=record
- _SemHandle:LongInt;
- _OpenCount:Byte;
- end;
- TPreq=^Treq;
- TPrep=^Trep;
- begin
- With TPreq(GlobalReqBuf)^
- do begin
- subf:=$00;
- If InitVal<0
- then _InitVal:=Lo(256+Initval)
- else _InitVal:=Lo(InitVal);
- UpString(SemName);SemName:=SemName+#0;
- move(semName[1],_SemName[0],ord(SemName[0]));
- _SemNameLen:=ord(semName[0])-1;
- end;
- F2SystemCall($20,SizeOf(treq),SizeOf(trep),result);
- With TPrep(GlobalReplyBuf)^
- do begin
- SemHandle:=Lswap(_SemHandle);
- OpenCount:=_OPenCount;
- end;
- OpenSemaphore:=(result=0);
- end;
-
-
- {F220/02 [3.x]}
- Function WaitOnSemaphore( SemHandle : LongInt;
- Wait_Time : Word ) : Boolean;
- { Decrement the semaphore value and wait if it is negative. If negative,}
- { the workstation will wait until it becomes non-negative or until a }
- { timeout occurs. }
- Type Treq=Record
- subf:byte;
- _SemHandle:Longint;
- _wait :word; { hi-lo }
- end;
- TPreq=^Treq;
- begin
- With TPreq(GlobalReqBuf)^
- do begin
- subf:=$02;
- _semHandle:=Lswap(SemHandle);
- _wait:=swap(wait_Time);
- end;
- F2SystemCall($20,SizeOf(treq),0,result);
- WaitOnSemaphore:=(result=0);
- end;
-
-
- {F220/03 [3.x+]}
- Function SignalSemaphore(SemHandle:LongInt) : Boolean;
- { Increment the semaphore value and release if waiting. If any stations}
- { are waiting, the station that has been waiting the longest will be }
- { signalled to proceed }
- Type Treq=Record
- subf:byte;
- _semhandle:Longint;
- end;
- TPreq=^Treq;
- begin
- With TPreq(GlobalReqBuf)^
- do begin
- subf:=$03;
- _semHandle:=Lswap(SemHandle);
- end;
- F2SystemCall($20,SizeOf(treq),0,result);
- SignalSemaphore:=(result=0);
- end;
-
-
- {F220/04 [3.x+]}
- Function CloseSemaphore(SemHandle:LongInt) : Boolean;
- { Decrement the open count of a semaphore. When the open count goes }
- { to zero, the semaphore is destroyed. }
- Type Treq=Record
- subf:byte;
- _semhandle:Longint;
- end;
- TPreq=^Treq;
- begin
- With TPreq(GlobalReqBuf)^
- do begin
- subf:=$04;
- _semHandle:=Lswap(SemHandle);
- end;
- F2SystemCall($20,SizeOf(treq),0,result);
- CloseSemaphore:=(result=0);
- end;
-
-
- {F220/01 [2.x/3.x]}
- FUNCTION ExamineSemaphore(SemHandle:LongInt;
- VAR Value : Integer;
- VAR OpenCount : Word ) : Boolean;
- { The semaphore value that comes back is the count from the open call }
- { - the open count is incremented }
- { anytime a station opens the semaphore this can be used for controlling }
- { the number of users using your software }
- Type Treq=record
- subf:byte;
- _semHandle:Longint;
- end;
- Trep=record
- _Value:Byte;
- _OpenCount:Byte;
- end;
- TPreq=^Treq;
- TPrep=^Trep;
- BEGIN
- With TPreq(GlobalReqBuf)^
- DO begin
- subf:=$01;
- _semHandle:=Lswap(SemHandle);
- end;
- F2SystemCall($20,SizeOf(Treq),SizeOf(Trep),result);
- With TPrep(GlobalReplyBuf)^
- do begin
- if (_Value and $80)>0
- then Value:=254-_Value
- else Value:=_Value;
- OpenCount:=_OpenCount;
- end;
- ExamineSemaphore := (result = 0);
- END;
-
- {F217/F1 [2.15+? 3.x+]}
- Function GetConnectionsSemaphores(ConnNbr:Word;
- {i/o} Var seqNbr:Word;
- {out} Var NbrOfSemaLeft:Byte;
- {out} Var SemaInfo:TconnSema):Boolean;
- { To be called iteratively. Inital seqNbr=1. Iterate until seqNbr
- becomes 0 (or until NbrOfSemaLeft becomes 0).
-
- This function can return information about several semaphores at the
- same time. However, the size of the reply buffer is limited, causing
- several as of now unsolvable problems. For now this function will
- return information on a per semaphore basis. }
- Type Treq=Record
- len:word;
- subf:byte;
- _ConnNbr:word; {lo-hi}
- _SeqNbr:word; {lo-hi}
- end;
- Trep=record
- _NextSeqNbr:word;
- _nbrOfSema:byte; { word (lo-hi) ? }
- _unknown:byte; { -^ }
- _SemaInfoBuf:array[1..508] of byte;
- end;
- TPreq=^Treq;
- TPrep=^Trep;
- Var i,t:Byte;
- begin
- With TPreq(GlobalReqBuf)^
- do begin
- len:=SizeOf(Treq)-2;
- subf:=$F1;
- _ConnNbr:=ConnNbr;
- _SeqNbr:=SeqNbr;
- end;
- F2SystemCall($17,SizeOf(treq),SizeOf(trep),result);
- if result=0
- then With TPrep(GlobalReplyBuf)^
- do begin
- NbrOfSemaLeft:=(_NbrOfSema-1);
- if NbrOfSemaLeft=0
- then seqNbr:=0
- else seqNbr:=seqNbr+1; { unfortunately, _NextSeqNbr returns no valid info. }
-
- Move(_SemaInfoBuf[1],SemaInfo,7+_SemaInfoBuf[7]);
- With SemaInfo
- do begin
- Value:=swap(Value);
- TaskNbr:=swap(TaskNbr);
- end;
- end;
- GetConnectionsSemaphores:=(result=0);
- { 00 Successful C6 No console rights FD Bad connection number }
- end;
-
- {F217/F2 [2.15? 3.x+]}
- Function GetSemaphoreInformation(SemaName:String;
- {i/o} Var seqNbr:word;
- {out} Var OpenCount:word;
- Var SemValue:Integer;
- Var NbrOfSemaLeft:byte;
- Var info:TsemaInfoList):Boolean;
- Type Treq=Record
- len:word;
- subf:byte;
- _seqNbr: word;
- _semaName:string[127];
- end;
- Trep=record
- _NextSeqNbr:Word;
- _OpenCount:word;
- _SemValue:word;
- _NbrOfRecords:word;
- _SemaInfoBuf:array[1..514] of byte;
- end;
- TPreq=^Treq;
- TPrep=^Trep;
- begin
- UpString(SemaName);
- if SemaName[0]>#127
- then SemaName[0]:=#127;
- With TPreq(GlobalReqBuf)^
- do begin
- subf:=$F2;
- _seqNbr:=seqNbr;
- _SemaName:=SemaName;
- len:=4+ord(_SemaName[0]);
- end;
- F2SystemCall($17,SizeOf(treq),SizeOf(trep),result);
- With TPrep(GlobalReplyBuf)^
- do begin
- OpenCount:=_OpenCount;
- SemValue:=Integer(_SemValue);
- NbrOfSemaLeft:=_NbrOfRecords;
- move(_SemaInfoBuf,Info,SizeOf(TsemaInfoList));
- if NbrOfSemaLeft>100
- then seqNbr:=seqNbr+100
- else seqNbr:=0;
- end;
- GetSemaphoreInformation:=(result=0);
- { 00 Successful C6 No console rights }
- end;
-
-
- END.